package com.dbumama.market.web.weixin;

import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

//import com.google.zxing.BarcodeFormat;
//import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
//import com.javen.kit.ZxingKit;
//import com.javen.model.Order;


import com.dbumama.market.model.Order;
import com.dbumama.market.model.OrderItem;
import com.dbumama.market.web.core.annotation.RouteBind;
import com.dbumama.market.web.core.utils.StringUtils;
import com.jfinal.aop.Clear;
import com.jfinal.kit.HttpKit;

import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;
import com.jfinal.weixin.sdk.api.ApiConfig;
import com.jfinal.weixin.sdk.api.PaymentApi;
import com.jfinal.weixin.sdk.api.PaymentApi.TradeType;
import com.jfinal.weixin.sdk.jfinal.ApiController;
import com.jfinal.weixin.sdk.kit.IpKit;
import com.jfinal.weixin.sdk.kit.PaymentKit;
import com.jfinal.weixin.sdk.utils.JsonUtils;
import com.dbumama.market.web.core.vo.AjaxResult;





/**
 * @author Javen
 * 2016年3月19日
 */
@RouteBind(path = "pay")

public class WeixinPayController extends ApiController {

	
	static Log log=Log.getLog(WeixinApiController.class);
	private AjaxResult ajax = new AjaxResult();
	//商户相关资料
	String appid = PropKit.get("appId");
	String partner = PropKit.get("mch_id");
	String paternerKey = PropKit.get("paternerKey");
	String notify_url = PropKit.get("domain")+"/pay/pay_notify";
	
	
//	String appid = getProperty("appId");
//	String appid = "wxebe0194b1085622a";
//	String partner = "1450243102";
//	String paternerKey = "ethansun19861212ethansun19861212";
//	String notify_url = PropKit.get("domain")+"/pay/pay_notify";
	/**
	 * 如果要支持多公众账号，只需要在此返回各个公众号对应的  ApiConfig 对象即可
	 * 可以通过在请求 url 中挂参数来动态从数据库中获取 ApiConfig 属性值
	 */
	public ApiConfig getApiConfig() {
		ApiConfig ac = new ApiConfig();
		
		// 配置微信 API 相关常量
		ac.setToken(PropKit.get("token"));
		ac.setAppId(PropKit.get("appId"));
		ac.setAppSecret(PropKit.get("appSecret"));
//		ac.setToken("ylqtrip");
//		ac.setAppId("wxebe0194b1085622a");
//		ac.setAppSecret("20cfefd2d24fda8d29cc02b3db671c1f");
		
		/**
		 *  是否对消息进行加密，对应于微信平台的消息加解密方式：
		 *  1：true进行加密且必须配置 encodingAesKey
		 *  2：false采用明文模式，同时也支持混合模式
		 */
		ac.setEncryptMessage(PropKit.getBoolean("encryptMessage", false));
		ac.setEncodingAesKey(PropKit.get("encodingAesKey", "setting it in config file"));
		return ac;
	}
	
	public void index() {

		// openId，采用 网页授权获取 access_token API：SnsAccessTokenApi获取
		String openId=getPara("openId");
		String orderid=getPara("orderId");
		String total_fee=getPara("total_fee");
//		if (StrKit.isBlank(total_fee)) {
//			ajax.addError("请输入数字金额");
//			renderJson(ajax);
//			return;
//		}





		//根据orderid 在t_order_item里找name
		String productName = getProductName(orderid);
//


		// 统一下单文档地址：https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
		
		Map<String, String> params = new HashMap<String, String>();
		params.put("appid", appid);
		params.put("mch_id", partner);
		params.put("body", productName);
//		商户单号
		String out_trade_no=System.currentTimeMillis()+"";
//		out_trade_no写入t_order out_trade_no 数据库 写入订单表
		updateTransactionId(out_trade_no,orderid);
		params.put("out_trade_no", out_trade_no);


		int price=((int)(Float.valueOf(total_fee)*100));
		params.put("total_fee", price+"");
//		params.put("attach", JsonKit.toJson(new PayAttach(out_trade_no, 2, 3)));
		

		String ip = IpKit.getRealIp(getRequest());
		if (StrKit.isBlank(ip)) {
			ip = "127.0.0.1";
		}
		
		params.put("spbill_create_ip", ip);
		params.put("trade_type", TradeType.JSAPI.name());
		params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
		params.put("notify_url", notify_url);
		params.put("openid", openId);

		String sign = PaymentKit.createSign(params, paternerKey);
		params.put("sign", sign);
		
		String xmlResult = PaymentApi.pushOrder(params);
		
		System.out.println(xmlResult);
		Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
		
		String return_code = result.get("return_code");
		String return_msg = result.get("return_msg");
		if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
			ajax.addError(return_msg);
			renderJson(ajax);
			return;
		}
		String result_code = result.get("result_code");
		if (StrKit.isBlank(result_code) || !"SUCCESS".equals(result_code)) {
			ajax.addError(return_msg);
			renderJson(ajax);
			return;
		}
		// 以下字段在return_code 和result_code都为SUCCESS的时候有返回
		String prepay_id = result.get("prepay_id");
		
		Map<String, String> packageParams = new HashMap<String, String>();
		packageParams.put("appId", appid);
		packageParams.put("timeStamp", System.currentTimeMillis() / 1000 + "");
		packageParams.put("nonceStr", System.currentTimeMillis() + "");
		packageParams.put("package", "prepay_id=" + prepay_id);
		packageParams.put("signType", "MD5");
		String packageSign = PaymentKit.createSign(packageParams, paternerKey);
		packageParams.put("paySign", packageSign);
		
		String jsonStr = JsonUtils.toJson(packageParams);
		ajax.success(jsonStr);
		renderJson(ajax);
	}



	public Order getOutTradeNO(String out_trade_no) {

		Order result = Order.dao.findFirst("select * FROM "+Order.table+" where out_trade_no = ?",out_trade_no);
		return result;
	}

	public Order getOrderByTransactionId(String transaction_id) {
		Order result = Order.dao.findFirst("select * FROM "+Order.table+" where transaction_id = ?",transaction_id);
		return result;
	}


	public void updateTransactionId(String out_trade_no, String orderid){

		Order result = Order.dao.findFirst("select * FROM "+Order.table+" WHERE  id= ? ", orderid);
		result.setOutTradeNO(out_trade_no);
		result.update();
	}

	public String getProductName(String orderId){

		OrderItem result=OrderItem.dao.findFirst("select * FROM "+OrderItem.table+" WHERE order_id = ? ", orderId);

		return result.getName();
	}



	@Clear
	public void pay_notify() {
		//获取所有的参数
		StringBuffer sbf=new StringBuffer();
				 
		Enumeration<String>  en=getParaNames();
		while (en.hasMoreElements()) {
			Object o= en.nextElement();
			sbf.append(o.toString()+"="+getPara(o.toString()));
		}
		
		log.error("支付通知参数："+sbf.toString());
		
		// 支付结果通用通知文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
		String xmlMsg = HttpKit.readData(getRequest());
		System.out.println("支付通知="+xmlMsg);
		Map<String, String> params = PaymentKit.xmlToMap(xmlMsg);
		
		String appid  = params.get("appid");
		//商户号
		String mch_id  = params.get("mch_id");
		String result_code  = params.get("result_code");
		String openId      = params.get("openid");
		//交易类型
		String trade_type      = params.get("trade_type");
		//付款银行
		String bank_type      = params.get("bank_type");
		// 总金额
		String total_fee     = params.get("total_fee");
		//现金支付金额
		String cash_fee     = params.get("cash_fee");
		// 微信支付订单号
		String transaction_id      = params.get("transaction_id");
		// 商户订单号
		String out_trade_no      = params.get("out_trade_no");
		// 支付完成时间，格式为yyyyMMddHHmmss
		String time_end      = params.get("time_end");
		
		/////////////////////////////以下是附加参数///////////////////////////////////
		
		String attach      = params.get("attach");
		String fee_type      = params.get("fee_type");
		String is_subscribe      = params.get("is_subscribe");
		String err_code      = params.get("err_code");
		String err_code_des      = params.get("err_code_des");
		
		
		// 注意重复通知的情况，同一订单号可能收到多次通知，请注意一定先判断订单状态
		// 避免已经成功、关闭、退款的订单被再次更新
		Order order = getOutTradeNO(out_trade_no);


		if (order!= null) {
			if(PaymentKit.verifyNotify(params, paternerKey)){
				if (("SUCCESS").equals(result_code)) {

					//更新订单信息
//					log.warn("更新订单信息:"+attach);
					order.setShippingStatus(2);
					order.setOrderStatus(2);
					order.setPaymentStatus(2);
					order.setTransactionId(transaction_id);
					order.setUpdated(new Date());
					order.update();

					//发送通知等

					Map<String, String> xml = new HashMap<String, String>();
					xml.put("return_code", "SUCCESS");
					xml.put("return_msg", "OK");
					renderText(PaymentKit.toXml(xml));

					return;
				}
			}
		}
//		redirect("www.baidu.com");
		renderText("");
	}
	
	public String getCodeUrl(){
		String url="weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXX&time_stamp=XXXXX&nonce_str=XXXXX";
		String product_id="001";
		String timeStamp=Long.toString(System.currentTimeMillis() / 1000);
		String nonceStr=Long.toString(System.currentTimeMillis());
		Map<String, String> packageParams = new HashMap<String, String>();
		packageParams.put("appid", appid);
		packageParams.put("mch_id", partner);
		packageParams.put("product_id",product_id);
		packageParams.put("time_stamp", timeStamp);
		packageParams.put("nonce_str", nonceStr);
		String packageSign = PaymentKit.createSign(packageParams, paternerKey);
		
		return StringUtils.replace(url, "XXXXX", packageSign,appid,partner,product_id,timeStamp,nonceStr);
	}
	
	
}


